<template>
  <div class="custom-el-plus">
    <el-dialog
      v-model="showDialog"
      width="auto"
      :destroy-on-close="true"
      :close-on-click-modal="false"
      align-center
      title="任务编辑"
      @close="resetTask"
    >
      <div class="task-dialog">
        <div class="base-head">
          <div class="base-icon"></div>
          <p>基础信息编辑</p>
        </div>
        <div class="task-ruleForm">
          <el-form
            ref="ruleFormRef"
            :model="state.taskFormData"
            :rules="state.taskRules"
            label-width="auto"
            size="default"
          >
            <div class="top-item">
              <el-form-item label="任务名称" prop="taskName">
                <el-input
                  v-model="state.taskFormData.taskName"
                  style="width: 16.12vw"
                  maxlength="30"
                  placeholder="请输入名称"
                  clearable
                />
              </el-form-item>
              <el-form-item label="任务状态" required>
                <el-radio-group v-model="state.taskFormData.startup">
                  <el-radio :value="1">启用</el-radio>
                  <el-radio :value="0">停用</el-radio>
                </el-radio-group>
              </el-form-item>
            </div>
            <div class="middle-item">
              <el-form-item label="自动任务" required>
                <el-radio-group
                  v-model="state.taskFormData.isAuto"
                  :active-value="1"
                  :inactive-value="0"
                  style="width: 16.12vw"
                  @change="changeTaskAuto"
                >
                  <el-radio :value="1">是</el-radio>
                  <el-radio :value="0">否</el-radio>
                </el-radio-group>
              </el-form-item>
              <el-form-item label="启动时间" prop="autoStartTime">
                <el-time-picker
                  v-if="state.taskFormData.isAuto"
                  v-model="state.taskFormData.autoStartTime"
                  :disabled-hours="disabledStartHour"
                  :disabled-minutes="disabledStartMinutes"
                  style="width: 5.616vw"
                  value-format="HH:mm"
                  format="HH:mm"
                  placeholder=""
                />
                <el-time-picker
                  v-else
                  v-model="state.startTime"
                  disabled
                  style="width: 5.616vw"
                  placeholder=""
                />
              </el-form-item>
              <el-form-item label="停止时间" prop="autoEndTime">
                <el-time-picker
                  v-if="state.taskFormData.isAuto"
                  v-model="state.taskFormData.autoEndTime"
                  :disabled-hours="disabledEndHour"
                  :disabled-minutes="disabledEndMinutes"
                  value-format="HH:mm"
                  format="HH:mm"
                  style="width: 5.616vw"
                  placeholder=""
                />
                <el-time-picker
                  v-else
                  v-model="state.endTime"
                  disabled
                  style="width: 5.616vw"
                  placeholder=""
                />
              </el-form-item>
              <el-form-item label="事件类型" prop="alarmDictPkIds">
                <el-select
                  v-model="state.taskFormData.alarmDictPkIds"
                  popper-class="custom-query-select"
                  placeholder="请选择事件类型"
                  multiple
                  collapse-tags
                  collapse-tags-tooltip
                  :max-collapse-tags="2"
                  :multiple-limit="10"
                  style="width: 16.588vw"
                  clearable
                >
                  <el-option
                    v-for="item in state.eventTypeList"
                    :key="item.pkId"
                    :label="item.alarmType"
                    :value="item.pkId"
                  />
                </el-select>
              </el-form-item>
            </div>
            <div class="bottom-item">
              <el-form-item label="抽帧频率" prop="frameCron">
                <el-select
                  v-model="state.taskFormData.frameCron"
                  placeholder="请选择抽帧频率"
                  style="width: 16.12vw"
                  popper-class="custom-query-select"
                  clearable
                >
                  <el-option
                    v-for="item in cronMapList"
                    :key="item.value"
                    :label="item.name"
                    :value="item.value"
                  />
                </el-select>
              </el-form-item>
              <el-form-item label="任务描述">
                <el-input
                  v-model="state.taskFormData.description"
                  style="width: 38.324vw"
                  :rows="1"
                  maxlength="50"
                  show-word-limit
                  type="textarea"
                  placeholder="请输入描述"
                  clearable
                />
              </el-form-item>
            </div>
          </el-form>
        </div>
        <div class="device-head">
          <div class="base-icon"></div>
          <p>关联设备管理</p>
          <el-button type="primary" @click="showMapMode">地图模式</el-button>
        </div>
        <div class="device-search-box">
          <!-- <span>行政区划</span>
          <el-select
            v-model="state.region"
            placeholder="全部"
            style="width: 16.328vw"
            popper-class="custom-query-select"
            clearable
          >
            <el-option
              v-for="item in regionList"
              :key="item.value"
              :label="item.name"
              :value="item.value"
            />
          </el-select> -->
          <span>设备类型</span>
          <el-select
            v-model="state.deviceType"
            placeholder="全部"
            popper-class="custom-query-select"
            style="width: 16.328vw"
            clearable
          >
            <el-option
              v-for="item in state.deviceTypeList"
              :key="item.code"
              :label="item.name"
              :value="item.code"
            />
          </el-select>
          <!-- <el-button plain @click="resetSearch">重置</el-button> -->
          <el-button type="primary" @click="searchDevice">查询</el-button>
          <el-button plain @click="openDeviceDialog">+ 新增</el-button>
        </div>
        <div class="device-table-box">
          <el-table
            :data="state.taskFormData.relativeDevice"
            style="width: 100%"
          >
            <el-table-column
              type="index"
              :index="getDeviceIndex"
              label="序号"
              width="80"
            />
            <el-table-column prop="deviceId" label="设备ID" show-overflow-tooltip/>
            <el-table-column prop="deviceTypeName" label="设备类型" />
            <el-table-column
              prop="address"
              label="设备位置"
              show-overflow-tooltip
            />
            <el-table-column prop="communicationTime" label="设备同步时间" />
            <el-table-column prop="onlineStatus" label="设备状态">
              <template #default="props">
                <div class="status-box">
                  <div v-if="props.row.onlineStatus" class="online-icon"></div>
                  <div v-else class="outline-icon"></div>
                  <span>{{ props.row.onlineStatus ? "在线" : "离线" }}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="150">
              <template #default="scope">
                <div class="device-btn-box">
                  <div class="switch-box">
                    <el-switch
                      size="small"
                      :active-value="1"
                      :inactive-value="0"
                      v-model="scope.row.status"
                      :loading="scope.row.updateLoading"
                      :before-change="beforeUpdate.bind(this, scope.row)"
                    />
                    <span class="statu-label">{{
                      scope.row.status ? "启用" : "停用"
                    }}</span>
                  </div>
                  <span class="btn-delete" @click="deleteDevice(scope.row)"
                    >移除</span
                  >
                </div>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <div class="device-page-box">
          <el-pagination
            style="margin-left: auto"
            v-model:current-page="state.currentDevicePage"
            :small="small"
            :page-size="state.devicePageSize"
            :background="true"
            layout="total, prev, pager, next"
            :total="state.taskFormData.totalRelativeDevice.length"
            @current-change="handleCurrentDeviceChange"
          />
        </div>
        <div class="algorithm-head">
          <div class="base-icon"></div>
          <p>关联算法管理</p>
          <el-button type="primary" @click="openAlgorithmDialog"
            >新增</el-button
          >
        </div>
        <div class="algorithm-table-box">
          <el-table
            :data="state.taskFormData.relativeAlgorithmList"
            style="width: 100%"
          >
            <el-table-column
              type="index"
              :index="getAlgorithmIndex"
              label="序号"
              width="80"
            />
            <el-table-column prop="name" label="算法名称" />
            <el-table-column prop="code" label="算法编码" />
            <el-table-column prop="creator" label="创建人" />
            <el-table-column
              prop="updateTime"
              label="算法更新时间"
              width="200"
            />
            <el-table-column label="操作" width="150">
              <template #default="scope">
                <div class="algorithm-btn-box">
                  <div class="switch-box">
                    <el-switch size="small" v-model="scope.row.enableStatus" />
                    <span class="statu-label">{{
                      scope.row.enableStatus ? "启用" : "停用"
                    }}</span>
                  </div>
                  <span class="btn-delete" @click="editEventType(scope.row)"
                    >移除</span
                  >
                </div>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <div class="algorithm-page-box">
          <el-pagination
            style="margin-left: auto"
            v-model:current-page="state.currentAlgorithmPage"
            :small="small"
            :page-size="state.algorithmPageSize"
            :background="true"
            layout="total, prev, pager, next"
            :total="state.taskFormData.totalRelativeAlgorithmList.length"
            @current-change="handleCurrentAlgorithmChange"
          />
        </div>
        <div class="task-btn-group">
          <el-button plain @click="cancleTask">取消</el-button>
          <el-button type="primary" @click="updateTaskById(ruleFormRef)"
            >保存</el-button
          >
        </div>
      </div>
    </el-dialog>
    <el-dialog
      v-model="state.mapDialogVisible"
      width="auto"
      destroy-on-close
      align-center
      title="地图"
      @close="resetDeviceMap"
    >
      <div class="pic-dialog">
        <div class="img-content">
          <div class="map-container" id="devicePositionMap"></div>
          <div class="btn-group">
            <el-button plain @click="cancleSelect">取消</el-button>
            <el-button type="primary" @click="addDevice">确定</el-button>
          </div>
        </div>
      </div>
    </el-dialog>
    <el-dialog
      title="设备列表"
      v-model="state.deviceDialogVisible"
      width="auto"
      destroy-on-close
      align-center
      @close="resetDeviceTable"
    >
      <div class="device-dialog">
        <div class="device-table">
          <el-table
            :data="state.notRelativeDeviceList"
            style="width: 100%"
            max-height="500"
            class="style-table"
            @selection-change="handleSelectionDeviceChange"
          >
            <el-table-column type="selection" width="55" />
            <el-table-column
              type="index"
              :index="getIndex"
              label="序号"
              width="80"
            />
            <el-table-column prop="deviceId" label="设备编号" width="200" />
            <el-table-column prop="deviceTypeName" label="设备类型" />
            <el-table-column prop="address" label="设备位置" width="200" show-overflow-tooltip/>
            <el-table-column prop="directionName" label="设备方向" />
            <el-table-column
              prop="communicationTime"
              label="通讯时间"
              width="200"
            />
            <el-table-column prop="onlineStatus" label="设备状态">
              <template #default="props">
                <div class="status-box">
                  <div v-if="props.row.onlineStatus" class="online-icon"></div>
                  <div v-else class="outline-icon"></div>
                  <span>{{ props.row.onlineStatus ? "在线" : "离线" }}</span>
                </div>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <div class="device-page-box">
          <el-pagination
            style="margin-left: auto"
            v-model:current-page="state.selectDevicePage"
            :small="small"
            :page-size="state.selectDevicePageSize"
            :background="true"
            layout="total, prev, pager, next"
            :total="state.notRelativeTotalNum"
            @current-change="handleSelectDeviceChange"
          />
        </div>
        <div class="btn-box">
          <el-button plain @click="cancleSelectDevice">取消</el-button>
          <el-button type="primary" @click="addRelativeDevice">确定</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>
<script setup>
import {
  computed,
  getCurrentInstance,
  onActivated,
  onBeforeUnmount,
  onDeactivated,
  onMounted,
  reactive,
  defineEmits,
  ref,
  h,
  watch,
  nextTick,
} from "vue";

import { ElMessage, ElMessageBox } from "element-plus";
// 引入请求方法
import { wgs84togcj02, getMaxMinLatLng } from "@/utils/toolUtils.js";
import { cronMapList } from "@/utils/constMapList.js";
import MapInit from "@/utils/mineMap/MapInit";
import MapMarker from "@/utils/mineMap/mapMarker.js";
// 引入图片
import device from "@/assets/img/liveData/mapPin.png";

const { proxy } = getCurrentInstance();
/* ====================================声明变量================================= */
const props = defineProps({
  taskShow: {
    type: Boolean,
    default: false,
  },
  taskCode: {
    type: String,
    default: "",
  },
});
const regionList = [
  {
    name: "桥东区",
    value: 1,
  },
  {
    name: "桥西区",
    value: 2,
  },
  {
    name: "宣化区",
    value: 3,
  },
];
const emit = defineEmits(["update:taskShow", "change"]);
const showDialog = computed({
  get() {
    return props.taskShow;
  },
  set(value) {
    emit("update:taskShow", value);
  },
});
const state = reactive({
  taskFormData: {
    taskName: "",
    pkid: "",
    alarmDictPkIds: [],
    startup: 1,
    frameCron: "",
    description: "",
    isAuto: 1,
    autoStartTime: "",
    autoEndTime: "",
    createUser: "",
    relativeDevice: [],
    relativeAlgorithmList: [],
    totalRelativeDevice: [],
    totalRelativeAlgorithmList: [],
  },
  taskRules: {
    taskName: [{ required: true, message: "请输入任务名称", trigger: "blur" }],
    frameCron: [
      { required: true, message: "请选择抽帧频率", trigger: "change" },
    ],
    alarmDictPkIds: [
      { required: true, message: "请至少选择一种事件类型", trigger: "change" },
    ],
    autoStartTime: [],
    autoEndTime: [],
  },
  startTime: "",
  endTime: "",
  region: "",
  deviceType: null,
  currentDevicePage: 1,
  devicePageSize: 5,
  currentAlgorithmPage: 1,
  algorithmPageSize: 5,
  selectDevicePage: 1,
  selectDevicePageSize: 100,
  mapDialogVisible: false,
  deviceDialogVisible: false,
  algorithmDialogVisible: false,
  mapImgsList: [
    {
      src: device,
      id: "device",
    },
  ],
  eventTypeList: [],
  deviceTypeList: [],
  notRelativeDeviceList: [],
  notRelativeTotalNum: 0,
  selectDevice: [],
  selectMarker: [],
});
const mapObject = {
  darkMapObj: null,
  deviceMarker: null,
  congruentPoint: {
    type: "FeatureCollection",
    features: [],
  },
};
const ruleFormRef = ref(null);
/* ====================================事件方法================================= */
const disabledEndHour = () => {
  if (state.taskFormData.autoStartTime) {
    let startTime = state.taskFormData.autoStartTime.split(":");
    let startHour = startTime[0];
    return makeRange(0, startHour - 1);
  }
};
const disabledEndMinutes = (hour) => {
  if (state.taskFormData.autoStartTime) {
    let startTime = state.taskFormData.autoStartTime.split(":");
    let startHour = startTime[0];
    let startMin = startTime[1];
    if (hour == startHour) {
      return makeRange(0, startMin);
    }
  }
};
const disabledStartHour = () => {
  if (state.taskFormData.autoEndTime) {
    let endTime = state.taskFormData.autoEndTime.split(":");
    let endHour = endTime[0];
    return makeRange(endHour, 23);
  }
};
const disabledStartMinutes = (hour) => {
  if (state.taskFormData.autoEndTime) {
    let endTime = state.taskFormData.autoEndTime.split(":");
    let endHour = endTime[0];
    let endMin = endTime[1];
    if (endHour == hour) {
      return makeRange(endMin, 59);
    }
  }
};
const getDeviceIndex = (index) => {
  return (state.currentDevicePage - 1) * state.devicePageSize + index < 9
    ? "0" + ((state.currentDevicePage - 1) * state.devicePageSize + (index + 1))
    : (state.currentDevicePage - 1) * state.devicePageSize + (index + 1);
};
const getAlgorithmIndex = (index) => {
  return (state.currentAlgorithmPage - 1) * state.algorithmPageSize + index < 9
    ? "0" +
        ((state.currentAlgorithmPage - 1) * state.algorithmPageSize +
          (index + 1))
    : (state.currentAlgorithmPage - 1) * state.algorithmPageSize + (index + 1);
};
const getIndex = (index) => {
  return index < 9 ? "0" + (index + 1) : index + 1;
};
const changeTaskAuto = (val) => {
  if (val) {
    state.taskRules.autoStartTime = [
      { required: true, message: "请选择启动时间", trigger: "change" },
    ];
    state.taskRules.autoEndTime = [
      { required: true, message: "请选择停止时间", trigger: "change" },
    ];
  } else {
    state.taskRules.autoStartTime = [];
    state.taskRules.autoEndTime = [];
    // state.taskFormData.autoStartTime = "";
    // state.taskFormData.autoEndTime = "";
    nextTick(() => {
      ruleFormRef.value.clearValidate();
    });
  }
};
const searchDevice = () => {
  if (state.deviceType == null) {
    state.taskFormData.relativeDevice =
      state.taskFormData.totalRelativeDevice.slice(
        (state.currentDevicePage - 1) * state.devicePageSize,
        state.currentDevicePage * state.devicePageSize
      );
  } else {
    state.taskFormData.relativeDevice = state.taskFormData.totalRelativeDevice
      .filter((item) => {
        return item.deviceType == state.deviceType;
      })
      .slice(
        (state.currentDevicePage - 1) * state.devicePageSize,
        state.currentDevicePage * state.devicePageSize
      );
  }
};
const resetSearch = () => {
  state.deviceType = null;
};
const openAlgorithmDialog = () => {
  ElMessage({
    message: "算法模块开发中",
    type: "info",
  });
};
const beforeUpdate = (row) => {
  return new Promise((resolve, reject) => {
    row.updateLoading = true;
    changeDeviceFrameStatus({
      pkId: row.pkId,
      status: !row.status ? 1 : 0,
    })
      .then((res) => {
        let status = "";
        if (row.status) {
          status = "停用";
        } else {
          status = "启用";
        }
        ElMessage({
          message: `设备${status}成功`,
          type: "success",
        });
        return resolve(true);
      })
      .catch((error) => {
        let status = "";
        if (row.status) {
          status = "停用";
        } else {
          status = "启用";
        }
        ElMessage({
          message: `设备${status}失败`,
          type: "error",
        });
        return reject();
      })
      .finally(() => {
        row.updateLoading = false;
      });
  });
};
const showMapMode = () => {
  state.mapDialogVisible = true;
  nextTick(() => {
    initMap().then(() => {
      getDeviceList().then((res) => {
        state.notRelativeDeviceList = res.list.filter(
          (item) =>
            !state.taskFormData.totalRelativeDevice.some(
              (relItem) => item.deviceId == relItem.deviceId
            )
        );
        let maxMinLatlng = getMaxMinLatLng(
          state.notRelativeDeviceList.map((item) => {
            return { lng: item.longitude, lat: item.latitude };
          })
        );
        mapObject.darkMapObj.fitBounds(maxMinLatlng, {
          padding: { top: 100, bottom: 100, left: 100, right: 100 },
        });
        mapObject.congruentPoint.features = formCongruentData(
          state.notRelativeDeviceList
        );
        addMarkers(mapObject.congruentPoint);
      });
    });
  });
};
const handleSelectDeviceChange = (val) => {
  getDeviceList().then((res) => {
    state.totalNotRelativeDeviceList = res.list.filter(
      (item) =>
        !state.taskFormData.totalRelativeDevice.some(
          (relItem) => item.deviceId == relItem.deviceId
        )
    );
    state.notRelativeTotalNum = state.totalNotRelativeDeviceList.length;
    state.notRelativeDeviceList = state.totalNotRelativeDeviceList.slice(
      (val - 1) * state.selectDevicePageSize,
      val * state.selectDevicePageSize
    );
  });
};
const handleCurrentDeviceChange = () => {
  state.taskFormData.relativeDevice =
    state.taskFormData.totalRelativeDevice.slice(
      (state.currentDevicePage - 1) * state.devicePageSize,
      state.currentDevicePage * state.devicePageSize
    );
};
const handleCurrentAlgorithmChange = () => {};
const openDeviceDialog = () => {
  state.deviceDialogVisible = true;
  getDeviceList().then((res) => {
    state.totalNotRelativeDeviceList = res.list.filter(
      (item) =>
        !state.taskFormData.totalRelativeDevice.some(
          (relItem) => item.deviceId == relItem.deviceId
        )
    );
    state.notRelativeTotalNum = state.totalNotRelativeDeviceList.length;
    state.notRelativeDeviceList = state.totalNotRelativeDeviceList.slice(
      (state.selectDevicePage - 1) * state.selectDevicePageSize,
      state.selectDevicePage * state.selectDevicePageSize
    );
  });
};
const handleSelectionDeviceChange = (row) => {
  state.selectDevice = row;
};
const addRelativeDevice = () => {
  if (!state.selectDevice.length) {
    ElMessage({
      message: "请至少选择一个设备",
      type: 'warning',
      duration: 2000
    })
    return;
  }
  ElMessageBox({
    title: "",
    cancelButtonClass: "messagebox-cancel-btn",
    confirmButtonClass: "messagebox-confirm-btn",
    customStyle: {
      backgroundColor: "#0D172F",
      borderRadius: "8px",
    },
    message: h("p", null, [
      h("div", { style: "color: #A5ADBA; margin: 2.781vh 0 3.708vh 0.624vw" }, "确认添加选中设备?"),
    ]),
    showCancelButton: true,
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    beforeClose: (action, instance, done) => {
      if (action === "confirm") {
        instance.confirmButtonLoading = true;
        instance.confirmButtonText = "loading...";
        let devicePkids = [];
        state.selectDevice.forEach((item) => {
          devicePkids.push(item.pkId);
        });
        let promiseArr = state.selectDevice?.map((item) => {
          return new Promise((resolve, reject) => {
            changeDeviceFrameStatus({
              pkId: item.pkId,
              status: 1,
            }).then((res) => {
              resolve(res);
            });
          });
        });
        Promise.all(promiseArr).then((res) => {
          console.log("修改状态成功");
        });
        addRelativeDeviceById({
          taskPkId: props.taskCode,
          devicePkIds: devicePkids,
        })
          .then((res) => {
            ElMessage({
              type: "success",
              message: `添加设备成功`,
              duration: 2000,
            });
            done();
            instance.confirmButtonLoading = false;
            state.deviceDialogVisible = false;
            state.selectDevice.forEach((item) => {
              // 默认添加设备状态开启
              item.status = 1;
            });
            state.taskFormData.totalRelativeDevice =
              state.taskFormData.totalRelativeDevice.concat(state.selectDevice);
            state.taskFormData.relativeDevice =
              state.taskFormData.totalRelativeDevice.slice(
                (state.currentDevicePage - 1) * state.devicePageSize,
                state.currentDevicePage * state.devicePageSize
              );
          })
          .catch((err) => {
            instance.confirmButtonLoading = false;
            state.deviceDialogVisible = false;
            ElMessage({
              type: "error",
              message: `添加设备失败`,
              duration: 2000,
            });
          });
      } else {
        done();
      }
    },
  }).then((action) => {});
};
const cancleSelectDevice = () => {
  state.deviceDialogVisible = false;
};
const resetDeviceTable = () => {
  state.notRelativeDeviceList = [];
  state.selectDevicePage = 1;
};
const resetDeviceMap = () => {
  state.selectMarker = [];
};
const cancleSelect = () => {
  state.mapDialogVisible = false;
};
const addDevice = () => {
  ElMessageBox({
    title: "",
    cancelButtonClass: "messagebox-cancel-btn",
    confirmButtonClass: "messagebox-confirm-btn",
    customStyle: {
      backgroundColor: "#0D172F",
      borderRadius: "8px",
    },
    message: h("p", null, [
      h("div", { style: "color: #A5ADBA; margin: 2.781vh 0 3.708vh 0.624vw" }, "确认添加地图中选中设备?"),
    ]),
    showCancelButton: true,
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    beforeClose: (action, instance, done) => {
      if (action === "confirm") {
        instance.confirmButtonLoading = true;
        instance.confirmButtonText = "loading...";
        let devicePkids = [];
        let deviceList = state.selectMarker.map((item) => {
          return item.markerOption.properties;
        });
        deviceList.forEach((item) => {
          devicePkids.push(item.pkId);
          // 默认添加设备状态开启
          item.status = 1;
        });
        let promiseArr = deviceList?.map((item) => {
          return new Promise((resolve, reject) => {
            changeDeviceFrameStatus({
              pkId: item.pkId,
              status: 1,
            }).then((res) => {
              resolve(res);
            });
          });
        });
        Promise.all(promiseArr).then((res) => {
          console.log("修改状态成功");
        });
        addRelativeDeviceById({
          taskPkId: props.taskCode,
          devicePkIds: devicePkids,
        })
          .then((res) => {
            done();
            instance.confirmButtonLoading = false;
            state.mapDialogVisible = false;
            state.taskFormData.totalRelativeDevice =
              state.taskFormData.totalRelativeDevice.concat(deviceList);
            state.taskFormData.relativeDevice =
              state.taskFormData.totalRelativeDevice.slice(
                (state.currentDevicePage - 1) * state.devicePageSize,
                state.currentDevicePage * state.devicePageSize
              );
            ElMessage({
              type: "success",
              message: `添加设备成功`,
              duration: 2000,
            });
          })
          .catch((err) => {
            instance.confirmButtonLoading = false;
            state.mapDialogVisible = false;
            ElMessage({
              type: "error",
              message: `添加设备失败`,
              duration: 2000,
            });
          });
      } else {
      }
    },
  }).then((action) => {});
};
const deleteDevice = (row) => {
  if (state.taskFormData.totalRelativeDevice.length < 2) {
    ElMessage({
      message: "任务至少关联一个设备",
      type: "warning",
      duration: 2000,
    });
    return;
  }
  ElMessageBox({
    title: "",
    cancelButtonClass: "messagebox-cancel-btn",
    confirmButtonClass: "messagebox-confirm-btn",
    customStyle: {
      backgroundColor: "#0D172F",
      borderRadius: "8px",
    },
    message: h("p", null, [
      h("div", { style: "color: #A5ADBA; margin: 2.781vh 0 3.708vh 0.624vw" }, "确认移除此设备?"),
    ]),
    showCancelButton: true,
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    beforeClose: (action, instance, done) => {
      if (action === "confirm") {
        instance.confirmButtonLoading = true;
        instance.confirmButtonText = "loading...";
        deleteRelativeDeviceById({
          taskPkId: props.taskCode,
          devicePkIds: [row.pkId],
        })
          .then((res) => {
            ElMessage({
              type: "success",
              message: `移除设备成功`,
              duration: 2000,
            });
            done();
            instance.confirmButtonLoading = false;
            state.taskFormData.totalRelativeDevice =
              state.taskFormData.totalRelativeDevice.filter((item) => {
                return item.pkId != row.pkId;
              });
            state.taskFormData.relativeDevice =
              state.taskFormData.totalRelativeDevice.slice(
                (state.currentDevicePage - 1) * state.devicePageSize,
                state.currentDevicePage * state.devicePageSize
              );
          })
          .catch((err) => {
            instance.confirmButtonLoading = false;
            ElMessage({
              type: "error",
              message: `移除设备失败`,
              duration: 2000,
            });
          });
      } else {
        done();
      }
    },
  }).then((action) => {});
};
const cancleTask = () => {
  showDialog.value = false;
};
const updateTaskById = async (formEl) => {
  await formEl.validate((valid, fields) => {
    if (valid) {
      let param = {
        pkId: props.taskCode,
        taskName: state.taskFormData.taskName,
        description: state.taskFormData.description,
        isAuto: state.taskFormData.isAuto,
        autoStartTime: "",
        autoEndTime: "",
        startup: state.taskFormData.startup,
        createUser: state.taskFormData.createUser || "",
        alarmDictPkIds: state.taskFormData.alarmDictPkIds.join(","),
        frameCron: state.taskFormData.frameCron,
        devicePkIds: [],
      };
      param.autoStartTime = state.taskFormData.autoStartTime
        ? state.taskFormData.autoStartTime + ":00"
        : "";
      param.autoEndTime = state.taskFormData.autoEndTime
        ? state.taskFormData.autoEndTime + ":00"
        : "";
      state.taskFormData.totalRelativeDevice?.forEach((item) => {
        param.devicePkIds.push(item.pkId);
      });
      if (!param.devicePkIds.length) {
        ElMessage({
          message: "任务至少关联一个设备",
          type: "warning",
          duration: 2000,
        });
        return;
      }
      updateTask(param)
        .then((res) => {
          ElMessage({
            message: "编辑任务成功",
            type: "success",
            duration: 2000,
          });
          showDialog.value = false;
          emit("change", true);
        })
        .catch((err) => {
          ElMessage({
            message: "编辑任务失败",
            type: "error",
            duration: 3000,
          });
        });
    } else {
      console.log("error submit!", fields);
    }
  });
};
const resetTask = () => {
  state.taskFormData = {
    taskName: "",
    pkid: "",
    alarmDictPkIds: [],
    startup: 1,
    frameCron: "",
    description: "",
    isAuto: 1,
    autoStartTime: "",
    autoEndTime: "",
    createUser: "",
    relativeDevice: [],
    totalRelativeDevice: [],
    relativeAlgorithmList: [],
    totalRelativeAlgorithmList: [],
  };
  state.taskRules = {
    taskName: [{ required: true, message: "请输入任务名称", trigger: "blur" }],
    frameCron: [
      { required: true, message: "请选择抽帧频率", trigger: "change" },
    ],
    alarmDictPkIds: [
      { required: true, message: "请至少选择一种事件类型", trigger: "change" },
    ],
    autoStartTime: [],
    autoEndTime: [],
  };
  state.deviceType = null;
  state.currentDevicePage = 1;
  state.currentAlgorithmPage = 1;
  state.eventTypeList = [];
  state.deviceTypeList = [];
  state.notRelativeDeviceList = [];
  state.selectDevice = [];
  state.selectMarker = [];
};
/* ====================================自定义方法================================= */
const extractHourMinute = (timeStr) => {
  // 使用正则表达式匹配时间格式
  const pattern = /^(\d{2}):(\d{2})(?::\d{2})?$/;
  const match = pattern.exec(timeStr);
  if (match) {
    const hour = match[1];
    const minute = match[2];
    return `${hour}:${minute}`;
  } else {
    return "";
  }
};
const makeRange = (start, end) => {
  const result = [];
  for (let i = start; i <= end; i++) {
    result.push(i);
  }
  return result;
};
const initMap = (lat = 40.76546125305629, lng = 114.88923193324109) => {
  return new Promise((resolve, reject) => {
    mapObject.darkMapObj = new MapInit("devicePositionMap", {
      center: [lng, lat],
      pitch: 0,
      zoom: 16,
    });
    mapObject.darkMapObj.on("click", onMouseClick);
    mapObject.darkMapObj.loadMapImgs(state.mapImgsList);
    let time = setInterval(() => {
      if (mapObject.darkMapObj && mapObject.darkMapObj.isStyleLoaded()) {
        clearInterval(time);
        resolve();
      }
    }, 100);
  });
};
const formCongruentData = (deviceData) => {
  return deviceData.map((item) => {
    return {
      type: "Feature",
      geometry: {
        type: "Point",
        coordinates: [+item.longitude, +item.latitude],
      },
      properties: item,
    };
  });
};
const addMarkers = (markerArr) => {
  mapObject.darkMapObj.addSource("deviceMarkerSrc", {
    type: "geojson",
    data: markerArr,
    generateId: true,
  });
  mapObject.darkMapObj.addLayer({
    id: "deviceMarkerLayer",
    type: "symbol",
    source: "deviceMarkerSrc",
    layout: {
      "icon-image": "device",
      "icon-size": 0.4,
      "icon-allow-overlap": true, //图标允许压盖
    },
  });
};
const onMouseClick = (e) => {
  var features = mapObject.darkMapObj.queryRenderedFeatures(e.point, {
    layers: ["deviceMarkerLayer"],
  });
  if (features.length) {
    let device = features[0].properties;
    let marker = state.selectMarker.find((item) => {
      return item.markerOption.pkId == device.pkId;
    });
    if (marker) {
      marker.remove();
      state.selectMarker = state.selectMarker.filter((item) => {
        return item.markerOption.pkId !== marker.markerOption.pkId;
      });
      return;
    }
    addSelectMarker(device);
  }
};
const addSelectMarker = (device) => {
  let marker = new MapMarker(mapObject.darkMapObj, {
    lnglat: [device.longitude, device.latitude],
    pkId: device.pkId,
    properties: device,
    width: "35px",
    height: "38px",
    url: "url(/ivam/mapPinGL.png)",
  });
  state.selectMarker.push(marker);
};
const getFormData = (data) => {
  state.taskFormData.taskName = data.taskName;
  state.taskFormData.pkId = data.pkId;
  state.taskFormData.description = data.description;
  state.taskFormData.startup = data.startup;
  state.taskFormData.isAuto = data.isAuto;

  state.taskFormData.autoStartTime = extractHourMinute(data.autoStartTime);
  state.taskFormData.autoEndTime = extractHourMinute(data.autoEndTime);

  state.taskFormData.alarmDictPkIds = data.alarmDictPkIds ? data.alarmDictPkIds.split(",") : [];
  state.taskFormData.frameCron = data.frameCron;
  state.taskFormData.createUser = data.createUser;
  state.taskFormData.totalRelativeDevice = data.deviceInfoList || [];
  state.taskFormData.relativeDevice =
    state.taskFormData.totalRelativeDevice.slice(
      (state.currentDevicePage - 1) * state.devicePageSize,
      state.currentDevicePage * state.devicePageSize
    );
  state.taskFormData.totalRelativeAlgorithmList = data.algorithmInfoList || [];
  state.taskFormData.relativeAlgorithmList =
    state.taskFormData.totalRelativeAlgorithmList.slice(
      (state.currentAlgorithmPage - 1) * state.algorithmPageSize,
      state.currentAlgorithmPage * state.algorithmPageSize
    );
  if (state.taskFormData.isAuto) {
    state.taskRules.autoStartTime = [
      { required: true, message: "请选择启动时间", trigger: "change" },
    ];
    state.taskRules.autoEndTime = [
      { required: true, message: "请选择停止时间", trigger: "change" },
    ];
  } else {
    state.taskRules.autoStartTime = [];
    state.taskRules.autoEndTime = [];
  }
};
/* ====================================接口方法================================= */
const addRelativeDeviceById = async (param) => {
  const res = await proxy.$http.postWithBody(
    "alarm/task/assocTaskAndDevice",
    param
  );
  if (res == 0) {
    throw res;
  }
  return res;
};
const deleteRelativeDeviceById = async (param) => {
  const res = await proxy.$http.postWithBody(
    "alarm/task/unAssocTaskAndDevice",
    param
  );
  if (res == 0) {
    throw res;
  }
  return res;
};
const changeDeviceFrameStatus = async (param) => {
  const res = await proxy.$http.postWithBody("device/update", param);
  if (res == 0) {
    throw res;
  }
  return res;
};
const getEventList = async () => {
  const res = await proxy.$http.postWithBody("alarm/dict/selectAll", {
    pageNum: null,
    pageSize: null,
    startup: 1,
  });
  if (res == 0) {
    throw res;
  }
  return res;
};
const getDeviceTypeList = async () => {
  const res = await proxy.$http.getFun("device/type");
  if (JSON.stringify(res) == "{}") {
    throw res;
  }
  return res;
};
const getDeviceList = async (param) => {
  const res = await proxy.$http.postWithBody("device/query", {
    reviewStatus: 1,
    frameStatus: 0,
    deviceType: null,
    onlineStatus: null,
    pageNum: null,
    pageSize: null,
  });
  if (JSON.stringify(res) == "{}") {
    throw res;
  }
  return res;
};
const getTaskDetailInfo = async (pkId) => {
  const res = await proxy.$http.postWithBody("alarm/task/details", {
    pkId: pkId,
  });
  if (JSON.stringify(res) == "{}") {
    throw res;
  }
  return res;
};
const updateTask = async (param) => {
  const res = await proxy.$http.postWithBody("alarm/task/update", param);
  if (res == 0) {
    throw res;
  }
  return res;
};
watch(
  () => props.taskCode,
  (newVal, oldVal) => {
    if (newVal) {
      getEventList().then((res) => {
        state.eventTypeList = res.list?.map((item) => {
          return {
            alarmType: item.alarmType,
            pkId: item.pkId,
          };
        });
      });
      getDeviceTypeList().then((res) => {
        state.deviceTypeList = res;
      });
      getTaskDetailInfo(newVal).then((res) => {
        getFormData(res);
      });
    }
  },
  {
    immediate: true,
  }
);
onMounted(() => {});
</script>
<style scoped lang="scss">
.task-dialog {
  width: pxTvw(1270);
  max-height: pxTvh(880);
  overflow-y: scroll;

  :deep(.el-radio-group) {
    .el-radio__input.is-checked .el-radio__inner {
      border: 4px solid #2275f0 !important;
    }

    .el-radio__input.is-checked .el-radio__inner:after {
      background: transparent;
    }
  }

  :deep(.el-select) {
    .el-select__wrapper {
      width: 100%;
    }
  }

  & > .base-head {
    margin: pxTvh(24) pxTvw(16) 0 pxTvw(16);
    height: pxTvh(32);
    @include elasticFN(flex-start, center);

    & > .base-icon {
      width: pxTvw(4);
      height: pxTvh(13);
      background: #3174ff;
    }

    & > p {
      font-family: PingFang SC, PingFang SC,sans-serif;
      font-weight: 500;
      @include computed-font(16);
      color: #e8f1ff;
      margin-left: pxTvw(8);
    }

    & > .el-button {
      margin-left: auto;
      height: pxTvh(36);
    }
  }

  & > .task-ruleForm {
    margin: pxTvh(24) pxTvw(16) 0 pxTvw(16);
    :deep(.el-form-item) {
      .el-form-item__label-wrap {
        margin-left: 0 !important;
      }
    }
    :deep(.el-date-editor) {
      .el-input__wrapper {
        .el-input__prefix {
          position: absolute;
          right: pxTvw(10);
        }
      }
    }
    .el-form {
      display: block;
    }

    .top-item {
      display: flex;
      & > .el-form-item:not(:first-child) {
        margin-left: pxTvw(24);
      }
    }

    .middle-item {
      display: flex;
      margin-top: pxTvh(24);
      & > .el-form-item:nth-child(2) {
        margin-left: pxTvw(33);
      }

      & > .el-form-item:nth-child(3) {
        margin-left: pxTvw(22);
      }

      & > .el-form-item:nth-child(4) {
        margin-left: pxTvw(24);
      }
    }

    .bottom-item {
      display: flex;
      margin: pxTvh(24) 0;
      & > .el-form-item:nth-child(2) {
        margin-left: pxTvw(31);
      }
    }
  }

  & > .device-head,
  & > .algorithm-head {
    margin: 0 pxTvw(16) 0 pxTvw(16);
    height: pxTvh(34);
    @include elasticFN(flex-start, center);

    & > .base-icon {
      width: pxTvw(4);
      height: pxTvh(13);
      background: #3174ff;
    }

    & > p {
      font-family: PingFang SC, PingFang SC,sans-serif;
      font-weight: 500;
      @include computed-font(16);
      color: #e8f1ff;
      margin-left: pxTvw(8);
    }

    & > .el-button {
      margin-left: auto;
      height: pxTvh(36);
    }
  }

  & > .device-search-box {
    @include elasticFN(flex-start, center);
    height: pxTvh(40);
    margin: pxTvh(16) pxTvw(16);
    font-family: PingFang SC, PingFang SC,sans-serif;
    font-weight: 400;
    @include computed_font(14);
    color: #ffffff;

    & > .el-select {
      margin-left: pxTvw(12);
    }

    & > span:nth-of-type(2) {
      margin-left: pxTvw(24);
    }

    & > .el-button:nth-of-type(1) {
      margin-left: pxTvw(24);
      height: pxTvh(36);
    }
    & > .el-button:nth-of-type(2) {
      margin-left: auto;
      height: pxTvh(36);
    }
  }

  & > .device-table-box {
    margin: 0 pxTvw(16);

    .status-box {
      @include elasticFN(flex-start, center);

      & > .online-icon {
        margin-right: pxTvw(8);
        width: pxTvw(8);
        height: pxTvw(8);
        background: #34ad54;
        border-radius: 50%;
      }

      & > .outline-icon {
        margin-right: pxTvw(8);
        width: pxTvw(8);
        height: pxTvw(8);
        background: #a5adba;
        border-radius: 50%;
      }
    }

    .device-btn-box {
      @include elasticFN(flex-start, center);

      & > .switch-box {
        height: 100%;
        @include elasticFN(flex-start, center);

        & > .statu-label {
          color: #d3dfff;
          height: 100%;
          margin-left: pxTvw(8);
        }
      }

      & > .btn-delete {
        cursor: pointer;
        margin-left: pxTvw(16);
        color: #377dff;
      }
    }
  }

  & > .device-page-box {
    margin: pxTvh(16) pxTvw(16) pxTvh(24) pxTvw(16);
  }

  & > .algorithm-table-box {
    margin: pxTvh(16) pxTvw(16) 0 pxTvw(16);

    .algorithm-btn-box {
      @include elasticFN(flex-start, center);

      & > .switch-box {
        height: 100%;
        @include elasticFN(flex-start, center);

        & > .statu-label {
          color: #d3dfff;
          height: 100%;
          margin-left: pxTvw(8);
        }
      }

      & > .btn-delete {
        cursor: pointer;
        margin-left: pxTvw(16);
        color: #377dff;
      }
    }

    .enable-box {
      width: pxTvw(56);
      height: pxTvh(24);
      border-radius: pxTvw(12);
      border: 1px solid #34ad54;
      color: #34ad54;
      @include elasticFN(center, center);
    }

    .unable-box {
      width: pxTvw(56);
      height: pxTvh(24);
      border-radius: pxTvw(12);
      border: 1px solid #a5adba;
      color: #a5adba;
      @include elasticFN(center, center);
    }
  }

  & > .algorithm-page-box {
    margin: pxTvh(16) pxTvw(16) 0 pxTvw(16);
  }

  & > .task-btn-group {
    display: flex;
    margin: pxTvh(30) pxTvw(16) pxTvh(4) pxTvw(16);

    & > .el-button:nth-child(1) {
      margin-left: auto;
    }
  }
}

.pic-dialog {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;

  .img-content {
    margin-top: pxTvh(16);
    padding: 0 pxTvh(16);
    color: rgba(207, 219, 252, 0.8);
    box-sizing: border-box;

    & > #devicePositionMap {
      width: pxTvw(1168);
      height: pxTvh(657);
    }

    & > .btn-group {
      margin-top: pxTvh(24);
      display: flex;
      justify-content: end;
    }
  }
}

.device-dialog {
  width: pxTvw(1200);

  & > .device-table {
    margin: pxTvh(24) pxTvw(16) 0 pxTvw(16);
  }
  & > .device-page-box {
    margin: pxTvh(16) pxTvw(16) pxTvh(24) pxTvw(16);
  }
  & > .btn-box {
    margin: pxTvh(24) pxTvw(16) pxTvh(16) pxTvw(16);
    display: flex;
    & > .el-button:nth-of-type(1) {
      margin-left: auto;
    }
  }
}

.status-box {
  @include elasticFN(flex-start, center);

  & > .online-icon {
    margin-right: pxTvw(8);
    width: pxTvw(8);
    height: pxTvw(8);
    background: #34ad54;
    border-radius: 50%;
  }

  & > .outline-icon {
    margin-right: pxTvw(8);
    width: pxTvw(8);
    height: pxTvw(8);
    background: #a5adba;
    border-radius: 50%;
  }
}
</style>
